#ifndef SOLVERS_HPP_
#   define SOLVERS_HPP_

#   include "Sol.hpp"
#   include "Moves.hpp"

#	define USING_CHECK_INSERT4

class SSolver
{
    public:
        SSolver(VRPTW& inVRPTW, const std::string& inName)
            :   slVRPTW(inVRPTW),
				slName(inName),
                slSol(inVRPTW)
        {}
        
        virtual ~SSolver()
        {}
        
        virtual void    execute(void* inArg) = 0;
        
        const Sol&      getResult() const
        {
			return slSol;
		}
        
    protected:
		VRPTW&			slVRPTW;
        std::string     slName;
        Sol             slSol;
};

class CTOR : public SSolver
{
    public:
        CTOR(VRPTW& inVRPTW, const std::string& inName)
            :   SSolver(inVRPTW, std::string("CTOR ") + inName)
        {}
        
        virtual void    execute(void* inArg) = 0;
};

class INCR : public SSolver
{
    public:
        INCR(VRPTW& inVRPTW, const std::string& inName)
            :   SSolver(inVRPTW, std::string("INCR ") + inName)
        {}
        
        virtual void    execute(void* inArg) = 0;
};

class Dummy : public CTOR
{
    public:
        Dummy(VRPTW& inVRPTW)
            :   CTOR(inVRPTW, "Dummy")
        {}
        
        void    execute(void* inArg);
};

class VND : public INCR
{
    public:
        VND(VRPTW& inVRPTW);
        ~VND();
        
        void    execute(void* inArg);
        
    protected:
        Sol::Eval                   vnRecordE;
        Sol                         vnRecord;
        Sol::Eval                   vnCurrentE;
        Sol                         vnCurrent;
        Sol::Eval                   vnNeighborE;
        Sol                         vnNeighbor;
        
        Moves::Move**				vnNeighborhoods;
        
        void	reset_neighborhoods();
};


class BasicInsert : public CTOR
{
	public:
		BasicInsert(VRPTW& inVRPTW)
			: 	CTOR(inVRPTW, "BasicInsert")
		{}
		~BasicInsert()
		{}
		
		void	execute(void* inArg);	// std::vector<unsigned>
		
	protected:
		virtual	unsigned	getNRandInsert() const;
};





#endif
